#include<iostream>
#include<cstdlib>
#include<unistd.h>
#include<cstdio>
#include<cstring>
#include<sys/types.h>
#include<wait.h>

using namespace std;
#define COMMAND_SIZE 1024
#define FORMAT "[%s@%s %s]#"

int g_argc = 0;


char* g_argv[COMMAND_SIZE];

//for test
char cwd[1024];
char cwdenv[1024];
const char *getHostName()
{
  const char * hostname =getenv("HOSTNAME");
  return hostname == NULL ? "None" : hostname ;
}
const char * getPwd()
{
  //const char * pwd =getenv("PWD");
	const char *pwd =getcwd(cwd,sizeof(cwd));
	if(pwd == NULL)
	{
		snprintf(cwdenv,sizeof(cwdenv),"PWD=%s",cwd);
		putenv(cwdenv);
		return "None";
	}
	return pwd == NULL ? "None" : pwd ;
}
const char *getHome()
{
	const char *home =getenv("HOME");
	return home == "" ? NULL:home;
}
string DirName(const char *pwd)
{
#define SLASH
	string dir=pwd;
	if(dir =="/")return "/";
	int pos =dir.rfind("/");
	if(pos ==string::npos)return "BUG?";
	return dir.substr(pos+1);
}
const char * getUserName()
{                                             
  const char * username =getenv("USER");             
  return username == NULL ? "None" : username ;
}                  

void MakecommandLine(char promptline[],int size)
{
  snprintf(promptline, size, FORMAT, getUserName(), getHostName(), DirName(getPwd()).c_str());

}


bool GetCommandLine(char *out,int size)    
{                                                                                   
  char * c = fgets(out,size,stdin);                  
  if(c == NULL)return false;         
  out[strlen(out)-1] = 0;

  if(strlen(out)==0)return false;
  //printf("echo %s",out);
  return true;
}

void PrintCommandLine()
{    
  char prompt[COMMAND_SIZE];
  MakecommandLine(prompt,COMMAND_SIZE);
  printf("%s",prompt);
  fflush(stdout);

}
bool CommandParse(char* commandline)
{
#define SEP " "
  g_argc = 0;
  g_argv[g_argc++] = strtok(commandline,SEP);
  while((g_argv[g_argc]=strtok(nullptr,SEP))!=nullptr) g_argc++;
	return g_argc > 0 ? true:false;
}
void printargv()
{
  for(int i=0;i<g_argc-1;i++)
  {
    printf("g_argv[%d]:%s\n",i,g_argv[i]);

  }
}
bool CheckAndExecBuitin()
{
	string cmd = g_argv[0];
	if(cmd == "cd")
	{
		//cd
		//string where;
		if(g_argc ==1)
		{

			string home = getHome();
			//where = gethome();
			if(home.empty())return true;
			chdir(home.c_str());
		}
		else
		{
			string where = g_argv[1];
			if(where =="-")
			{

			}
			else if(where == "~")
			{

			}
			else
			{
				chdir(where.c_str());
			}
		}
		return true;
	}
	return false;
}
void running()
{

  pid_t id = fork();
  if(id ==0)
  {
    //子进程
    execvp(g_argv[0],g_argv);
    exit(1);
  }
  pid_t rid = waitpid(id,nullptr,0);
  (void)rid;//使用一下rid
	return ;
}
int main()
{
  //printf("%s,%s,%s\n",getHostName(),getPwd(),getUserName());
	while(1)
	{

  //1.获取命令提示符号
  PrintCommandLine();


  //2.获取用户输入的命令
  char commandline[COMMAND_SIZE];
  if(GetCommandLine(commandline,sizeof(commandline)))
  {
   // printf("echo %s\n",commandline);

  }


  //3，拆分命令进行分析
  if(!CommandParse(commandline))
	  continue;
 // printargv();
  //printf("echo %s\n",commandline);
  //
  if(CheckAndExecBuitin())
	  continue;
  //4.执行命令
  running();
	}
	return 0;
}
